/*
 * An argument parser for ClockDomainArchitectureImpl, based on JSAP.
 * 
 * Copyright (c) 2008 Brigham Young University
 * 
 * This file is part of the BYU EDIF Tools.
 * 
 * BYU EDIF Tools is free software: you may redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 2 of the License, or (at your option) any
 * later version.
 * 
 * BYU EDIF Tools is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * A copy of the GNU General Public License is included with the BYU EDIF Tools.
 * It can be found at /edu/byu/edif/doc/gpl2.txt. You may also get a copy of the
 * license at <http://www.gnu.org/licenses/>.
 * 
 */
package edu.byu.ece.edif.util.jsap.commandgroups;

import java.util.LinkedHashSet;

import com.martiansoftware.jsap.FlaggedOption;
import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPResult;
import com.martiansoftware.jsap.Parameter;
import com.martiansoftware.jsap.Switch;

import edu.byu.ece.edif.util.jsap.JSAPCommandParser;

/**
 * A command-line argument parser for ClockDomainArchitectureImpl, based on
 * {@link JSAP} (Java-based Simple Argument Parser). This class handles the
 * parsing of all command-line arguments, ensuring that they are syntactically
 * correct. It also provides automatically-formated usage and help information (<code>--help</code>
 * option).
 * 
 * @see DWCCommandParser
 * @see JSAP
 * @see JSAPCommandParser
 * @see <a href="http://www.martiansoftware.com/jsap/doc/javadoc/index.html">
 * JSAP API</a>
 * @see <a href="http://www.martiansoftware.com/jsap/">JSAP Homepage</a>
 * @author Kevin Lundgreen
 */

public class ClockDomainCommandGroup extends AbstractCommandGroup {

    /**
     * Create a new ClockDomainCommandParser.
     */
    public ClockDomainCommandGroup() {
        /*
         * Parent constructor sets up common Parameters such as --help,
         * --version, --writeConfig, --useConfig, etc.
         */
        super();
        _ClockAnalyzerParameters = new LinkedHashSet<Parameter>();

        /*
         * File options: input_file, output_file, etc.
         */
        this
                .addCommand(new FlaggedOption(OUTPUT_FILE)
                        .setStringParser(JSAP.STRING_PARSER)
                        .setRequired(JSAP.NOT_REQUIRED)
                        .setShortFlag('o')
                        .setLongFlag("output")
                        .setUsageName("output_file")
                        .setHelp(
                                "Filename and path to the summary generated by the clock domain analayzer. If no file is specified, summary is output to stdout."));

        /*
         * Domain options
         */
        this.addCommand(new FlaggedOption(DOMAIN).setStringParser(JSAP.STRING_PARSER).setRequired(JSAP.NOT_REQUIRED)
                .setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("domain").setDefault("all").setAllowMultipleDeclarations(
                        JSAP.MULTIPLEDECLARATIONS).setList(JSAP.LIST).setListSeparator(LIST_DELIMITER).setHelp(
                        "A comma-separated list of domains to report."));

        this.addCommand(new Switch(SHOW_NO_DOMAIN).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("show_no_domain")
                .setDefault(FALSE).setHelp("Add cells and nets not in a domain to the report."));

        this
                .addCommand(new FlaggedOption(SHOW_CLOCK_CROSSINGS)
                        .setStringParser(JSAP.STRING_PARSER)
                        .setRequired(JSAP.NOT_REQUIRED)
                        .setShortFlag(JSAP.NO_SHORTFLAG)
                        .setLongFlag("show_clock_crossings")
                        .setAllowMultipleDeclarations(JSAP.MULTIPLEDECLARATIONS)
                        .setList(JSAP.LIST)
                        .setListSeparator(LIST_DELIMITER)
                        .setHelp(
                                "The domain crossing to report. This option must be followed by 2 comma-separated domains.  e.g. --show_clock_crossings clk1,clk2 or --show_clock_crossings clk1,all."));

        this
                .addCommand(new FlaggedOption(CREATE_DOTTY_GRAPH)
                        .setStringParser(JSAP.STRING_PARSER)
                        .setRequired(JSAP.NOT_REQUIRED)
                        .setShortFlag(JSAP.NO_SHORTFLAG)
                        .setLongFlag("create_dotty_graph")
                        .setAllowMultipleDeclarations(JSAP.MULTIPLEDECLARATIONS)
                        .setList(JSAP.LIST)
                        .setListSeparator(LIST_DELIMITER)
                        .setHelp(
                                "The name of an EdifCellInstance to display in a graph.  Also required is the name of the port to show.  e.g.  --create_dotty_graph fd_inst,d"));

        this.addCommand(new Switch(SHOW_CELLS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("show_cells").setDefault(
                FALSE).setHelp("Show listing of all EdifCellInstances in the domain(s) specified by --domain."));

        this.addCommand(new Switch(SHOW_NETS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("show_nets")
                .setDefault(FALSE).setHelp("Show listing of all EdifNets in the domain(s) specified by --domain."));

        this.addCommand(new Switch(SHOW_SYNCHRONOUS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("show_synchronous")
                .setDefault(FALSE).setHelp(
                        "Show listing of all synchronous EdifCellInstances in the domain(s) specified by --domain."));

        this.addCommand(new Switch(SHOW_ASYNCHRONOUS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("show_asynchronous")
                .setDefault(FALSE).setHelp(
                        "Show listing of all asynchronous EdifCellInstances in the domain(s) specified by --domain."));

        this.addCommand(new Switch(SHOW_GATED_CLOCKS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("show_gated_clocks")
                .setDefault(FALSE).setHelp("Show listing of all clock domains not driven by a BUFG, DCM, or DLL."));

        this.addCommand(new Switch(SHOW_ASYNCHRONOUS_RESETS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag(
                "show_asynchronous_resets").setDefault(FALSE).setHelp(
                "Show listing of all nets driving asynchronous reset ports."));

        this.addCommand(new Switch(SHOW_ASYNCHRONOUS_RESET_CELLS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag(
                "show_asynchronous_reset_cells").setDefault(FALSE).setHelp(
                "Show listing of all nets driving asynchronous reset ports, along with the cells they drive."));

        this.addCommand(new Switch(DO_SCC_ANALYSIS).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("do_scc_analysis")
                .setDefault(FALSE).setHelp(
                        "Show listing of all asynchronous EdifCellInstances in the domain(s) specified by --domain."));

        this.addCommand(new Switch(NO_IOB_FEEDBACK).setShortFlag(JSAP.NO_SHORTFLAG).setLongFlag("no_iob_feedback")
                .setDefault(FALSE).setHelp("Exclude IOBs from feedback analaysis."));
    }

    // //////////////////////////////////////////////////////////////////////
    // Protected Methods

    public static final String FALSE = "false";

    public static final String OUTPUT_FILE = "output";

    public static final char LIST_DELIMITER = ',';

    public static final String DOMAIN = "domain";

    public static final String SHOW_NO_DOMAIN = "show_no_domain";

    public static final String SHOW_CLOCK_CROSSINGS = "show_clock_crossings";

    public static final String CREATE_DOTTY_GRAPH = "create_dotty_graph";

    public static final String SHOW_CELLS = "show_cells";

    public static final String SHOW_NETS = "show_nets";

    public static final String SHOW_SYNCHRONOUS = "show_synchronous";

    public static final String SHOW_ASYNCHRONOUS = "show_asynchronous";

    public static final String DO_SCC_ANALYSIS = "do_scc_analysis";

    public static final String NO_IOB_FEEDBACK = "no_iob_feedback";

    public static final String SHOW_GATED_CLOCKS = "show_gated_clocks";

    public static final String SHOW_ASYNCHRONOUS_RESETS = "show_asynchronous_resets";

    public static final String SHOW_ASYNCHRONOUS_RESET_CELLS = "show_asynchronous_reset_cells";

    /**
     * Ordered List of parameters to easily register them all or print them all
     */
    protected LinkedHashSet<Parameter> _ClockAnalyzerParameters;

    /**
     * {@link JSAPResult} object used to store the parameters after being
     * parsed.
     */
    protected JSAPResult _result;
}
